package com.cswangdao.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.cswangdao.domain.dto.WXCheckoutDTO;
import com.cswangdao.domain.model.*;
import com.cswangdao.domain.vo.CartTotal;
import com.cswangdao.domain.vo.WXCheckoutVo;
import com.cswangdao.domain.vo.WXCartIndexVo;
import com.cswangdao.mapper.*;
import com.cswangdao.service.CartService;
import com.cswangdao.utils.CouponUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class CartServiceImpl implements CartService {

    @Autowired
    private MarketCartMapper cartMapper;

    @Autowired
    private MarketGoodsMapper goodsMapper;

    @Autowired
    private MarketGoodsProductMapper goodsProductMapper;

    @Autowired
    private MarketAddressMapper addressMapper;

    @Autowired
    private MarketCouponMapper couponMapper;


    @Autowired
    private MarketSystemMapper systemMapper;

    @Autowired
    private CouponUtil couponUtil;

    @Override
    public Integer getCartGoodsCount() {
        // TODO 获取用户ID
        List<Integer> num = cartMapper.getGoodsCountByUserId(1);
        Integer i = num.stream().reduce(Integer::sum).orElseGet(() -> 0);
        return i;
    }

    @Override
    public Integer addGoodsToCart(Map map) {

        Integer goodsId = parseObjectToInt(map.get("goodsId"));
        Short number = Short.parseShort(map.get("number").toString());
        Integer productId = parseObjectToInt(map.get("productId"));

        //获取商品规格库存信息
        MarketGoodsProduct goodsProduct = goodsProductMapper.getById(productId);
        if (goodsProduct.getNumber() < number) {
            throw new RuntimeException("商品库存不足");
        }

        //获取用户购物车商品数量
        int total = cartMapper.getGoodsCountByUserId(1).stream().reduce(Integer::sum).orElseGet(() -> 0);
        int res = total + number;

        Date now = new Date();
        //判断是否已经存在该商品，如果存在，则更新数量
        MarketCart hasCart = cartMapper.isExist(1, goodsId, productId);
        if (Objects.nonNull(hasCart)) {
            //存在
            Short oldNumber = hasCart.getNumber();
            int newNumber = oldNumber + number;
            hasCart.setNumber((short) newNumber);
            hasCart.setUpdateTime(now);
            cartMapper.updateCartInfo(hasCart);
            return res;
        }

        //不存在
        MarketGoods goods = goodsMapper.getById(goodsId);

        // TODO 获取用户ID 利用ThreadLocal
        MarketCart cart = MarketCart.builder()
                .userId(1)
                .goodsId(goodsId)
                .goodsSn(goods.getGoodsSn())
                .goodsName(goods.getName())
                .productId(productId)
                .price(goods.getRetailPrice())
                .number(number)
                .specifications(goodsProduct.getSpecifications())
                .checked(true)
                .picUrl(goods.getPicUrl())
                .addTime(now)
                .updateTime(now)
                .build();


        cartMapper.addCartInfo(cart);
        return res;
    }

    @Override
    public WXCartIndexVo getCartListByUserId() {

        // TODO 获取用户ID
        List<MarketCart> carts = cartMapper.getCartListByUserId(1);

        // 获取所选商品的金额
        BigDecimal checkedGoodsAmount = carts.stream().filter(MarketCart::getChecked)
                .map(cart -> cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())))
                .reduce(BigDecimal::add)
                .orElseGet(() -> BigDecimal.ZERO);

        // 获取所选商品的数量
        Integer checkedGoodsCount = carts.stream().filter(MarketCart::getChecked)
                .map(marketCart -> (int) marketCart.getNumber())
                .reduce(Integer::sum)
                .orElseGet(() -> 0);

        // 获取所有商品的金额
        BigDecimal goodsAmount = carts.stream().map(cart -> cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())))
                .reduce(BigDecimal::add)
                .orElseGet(() -> BigDecimal.ZERO);

        // 获取所有商品的数量
        Integer goodsCount = carts.stream().map(marketCart -> (int) marketCart.getNumber())
                .reduce(Integer::sum)
                .orElseGet(() -> 0);

        CartTotal cartTotal = CartTotal.builder()
                .checkedGoodsAmount(checkedGoodsAmount)
                .checkedGoodsCount(checkedGoodsCount)
                .goodsAmount(goodsAmount)
                .goodsCount(goodsCount)
                .build();

        return WXCartIndexVo.builder()
                .cartList(carts)
                .cartTotal(cartTotal)
                .build();

    }

    @Override
    public WXCartIndexVo modifyCartCheckedStatus(Map map) {

        // TODO 获取用户ID
        map.put("userId", 1);
        map.put("updateTime", new Date());
        cartMapper.updateCartCheckedStatus(map);
        WXCartIndexVo res = getCartListByUserId();
        return res;
    }

    @Override
    public Integer fastAddGoodsToCart(Map map) {
        Integer goodsId = parseObjectToInt(map.get("goodsId"));
        Short number = Short.parseShort(map.get("number").toString());
        Integer productId = parseObjectToInt(map.get("productId"));

        //获取商品规格库存信息
        MarketGoodsProduct goodsProduct = goodsProductMapper.getById(productId);
        if (goodsProduct.getNumber() < number) {
            throw new RuntimeException("商品库存不足");
        }
        Date now = new Date();
        //判断是否已经存在该商品，如果存在，覆盖原有记录
        // TODO 获取用户ID
        MarketCart hasCart = cartMapper.isExist(1, goodsId, productId);
        if (Objects.nonNull(hasCart)) {
            //存在
            hasCart.setNumber(number);
            hasCart.setUpdateTime(now);
            cartMapper.updateCartInfo(hasCart);
            return hasCart.getId();
        }

        //不存在,新增记录
        MarketGoods goods = goodsMapper.getById(goodsId);

        // TODO 获取用户ID 利用ThreadLocal
        MarketCart cart = MarketCart.builder()
                .userId(1)
                .goodsId(goodsId)
                .goodsSn(goods.getGoodsSn())
                .goodsName(goods.getName())
                .productId(productId)
                .price(goods.getRetailPrice())
                .number(number)
                .specifications(goodsProduct.getSpecifications())
                .checked(true)
                .picUrl(goods.getPicUrl())
                .addTime(now)
                .updateTime(now)
                .build();


        cartMapper.addCartInfo(cart);
        return cart.getId();

    }

    @Override
    public WXCheckoutVo getCartCheckoutVo(WXCheckoutDTO wxCheckoutDTO) {

        Integer addressId = wxCheckoutDTO.getAddressId();
        MarketAddress address = null;
        //获取地址信息
        if (addressId == 0) {
            // TODO 用户id
            //获取用户默认地址
            address = addressMapper.getDefaultAddressByUserId(1, 0);
        } else if (addressId > 0) {
            //获取指定地址
            address = addressMapper.getById(addressId);
        }

        Integer cartId = wxCheckoutDTO.getCartId();
        //记录购物车状态已选择列表
        List<MarketCart> checkedGoodsList = new ArrayList<>();
        //获取商品总价，优惠卷抵扣之前的价格
        BigDecimal goodsTotalPrice = BigDecimal.ZERO;
        if (cartId == 0) {
            //购物车去付款 TODO 获取用户ID
            List<MarketCart> cartList = cartMapper.getCartListByUserId(1);
            checkedGoodsList = cartList.stream().filter(MarketCart::getChecked).toList();
            goodsTotalPrice = cartList.stream().filter(MarketCart::getChecked)
                    .map(cart -> cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())))
                    .reduce(BigDecimal::add)
                    .orElseGet(() -> BigDecimal.ZERO);

        } else if (cartId > 0) {
            //立即购买
            MarketCart cart = cartMapper.getById(cartId);
            checkedGoodsList.add(cart);
            goodsTotalPrice = cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber()));
        }

        //获取优惠券信息
        MarketCoupon coupon = null;
        Integer couponNumber = 0;
       // boolean isCounponEffective = false;
        // TODO ?????
        Integer couponId = wxCheckoutDTO.getCouponId();
        // TODO 用户ID
        List<MarketCouponUser> couponUsers = couponUtil.availableCoupons(1, goodsTotalPrice);
        if (CollUtil.isNotEmpty(couponUsers)) {
            couponNumber = couponUsers.size();
            if (couponId > 0) {
                coupon = couponMapper.getById(couponId);
                long count = couponUsers.stream().filter(couponUser -> couponUser.getCouponId().equals(couponId)).count();
                if(count <= 0){
                    coupon = null;
                }
            } else if (couponId == 0) {
                //默认选取最合适的优惠卷
                // TODO 用户id
                List<Integer> couponIds = couponUsers.stream().map(MarketCouponUser::getCouponId).toList();
                List<MarketCoupon> coupons = couponMapper.getByIds(couponIds, couponIds.size());
                coupon = coupons.stream().max((o1, o2) -> o1.getDiscount().compareTo(o2.getDiscount())).orElseGet(() -> null);

            }
        }

        //订单总价，优惠券抵扣之后的价格
        BigDecimal orderTotalPrice;
        if (Objects.nonNull(coupon)) {
            //优惠券存在且有效
            orderTotalPrice = goodsTotalPrice.subtract(coupon.getDiscount());
        } else {
            orderTotalPrice = goodsTotalPrice;
        }

        //免运费的最小金额
        double freightMin = Double.parseDouble(systemMapper.getValueIsStringByName("market_express_freight_min"));

        //运费金额
        double freightValue = Double.parseDouble(systemMapper.getValueIsStringByName("market_express_freight_value"));

        //判断是否免运费
        double freight = goodsTotalPrice.compareTo(BigDecimal.valueOf(freightMin)) >= 0 ? 0 : freightValue;

        //实际支付金额，加上运费
        BigDecimal actualPrice = orderTotalPrice.add(BigDecimal.valueOf(freight));

        return WXCheckoutVo.builder()
                .actualPrice(actualPrice)
                .addressId(addressId)
                .availableCouponLength(couponNumber)
                .cartId(cartId)
                .checkedAddress(address)
                .checkedGoodsList(checkedGoodsList)
                .couponId(couponId)
                .couponPrice(coupon == null ? BigDecimal.ZERO : coupon.getDiscount() )
                .freightPrice(BigDecimal.valueOf(freight))
                .goodsTotalPrice(goodsTotalPrice)
                .grouponPrice(BigDecimal.ZERO)
                .grouponRulesId(0)
                .orderTotalPrice(orderTotalPrice)
                .userCouponId(wxCheckoutDTO.getUserCouponId())
                .build();
    }

    @Override
    public WXCartIndexVo deleteBatch(List<Integer> productIds) {
        // TODO 获取用户ID
        cartMapper.deleteByUserIdAndProductIds(1,productIds);
        WXCartIndexVo wxCartIndexVo = getCartListByUserId();
        return wxCartIndexVo;
    }

    @Override
    public void updateProductNumber(Map map) {
        int cartId = Integer.parseInt(map.get("id").toString());
        int number = Integer.parseInt(map.get("number").toString());
        int productId = Integer.parseInt(map.get("productId").toString());
        MarketGoodsProduct goodsProduct = goodsProductMapper.getById(productId);
        if(goodsProduct.getNumber() < number){
            throw new RuntimeException("商品库存不足");
        }
        cartMapper.updateProductNumber(cartId,number);
    }



    public Integer parseObjectToInt(Object object) {
        return Integer.parseInt(object.toString());
    }
}
